package org.xiaojinlong.tiger;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by jinlong on 2015/4/6.
 */
public class SLP {
    public static Map<String, Integer> interp(Stm ptr) {
        Map<String, Integer> table = new HashMap<>();
        if (((CompoundStm) ptr).first instanceof CompoundStm) {

        } else if (((CompoundStm) ptr).first instanceof AssignStm) {
            Integer value = null;
            AssignStm assignStm = (AssignStm) ((CompoundStm) ptr).first;
            if (assignStm.exp instanceof IdExp) {
                value = table.get(((IdExp) assignStm.exp).id);
            } else if (assignStm.exp instanceof NumExp) {
                value = ((NumExp) assignStm.exp).num;
            } else if (assignStm.exp instanceof OpExp) {

            } else if (assignStm.exp instanceof EseqExp) {

            }
            table.put(assignStm.id, value);

        } else if (((CompoundStm) ptr).first instanceof PrintStm) {

        } else {
            System.out.println("Error!");
        }

        return table;
    }

    public static void main(String[] args) {
        Stm program = new CompoundStm(
                new AssignStm("a", new OpExp(new NumExp(5), BinOp.PLUS, new NumExp(3))),
                new CompoundStm(
                        new AssignStm("b",
                                new EseqExp(
                                        new PrintStm(new PairExpList(new IdExp("a"), new LastExpList(new OpExp(new IdExp("a"), BinOp.MINUS, new NumExp(1))))),
                                        new OpExp(new NumExp(10), BinOp.TIMES, new IdExp("a")))),
                        new PrintStm(new LastExpList(new IdExp("b")))));
        Stm prog2 = new CompoundStm(
                new AssignStm("a", new NumExp(12)), null);

        System.out.println(interp(prog2));

    }
}

class CompoundStm implements Stm {
    Stm first;
    Stm last;

    CompoundStm(Stm _first, Stm _last) {
        first = _first;
        last = _last;
    }
}

class AssignStm implements Stm {
    String id;
    Exp exp;

    AssignStm(String _id, Exp _exp) {
        id = _id;
        exp = _exp;
    }
}

class PrintStm implements Stm {
    ExpList exps;

    PrintStm(ExpList _exps) {
        exps = _exps;
    }
}

class IdExp implements Exp {
    String id;

    IdExp(String _id) {
        id = _id;
    }
}

class NumExp implements Exp {
    Integer num;

    NumExp(Integer _num) {
        num = _num;
    }
}

class OpExp implements Exp {
    Exp left;
    BinOp op;
    Exp right;

    OpExp(Exp _left, BinOp _op, Exp _right) {
        left = _left;
        op = _op;
        right = _right;
    }
}

class EseqExp implements Exp {
    Stm stm;
    Exp exp;

    EseqExp(Stm _stm, Exp _exp) {
        stm = _stm;
        exp = _exp;
    }
}

class PairExpList implements ExpList {
    Exp head;
    ExpList tail;

    PairExpList(Exp _head, ExpList _tail) {
        head = _head;
        tail = _tail;
    }
}

class LastExpList implements ExpList {
    Exp last;

    LastExpList(Exp _last) {
        last = _last;
    }
}

enum BinOp {
    PLUS, MINUS, TIMES, DIV
}
